//============================================================================
// Name        : puzzle_region.cpp
// Author      : dfoelber
//============================================================================

// INCLUDES //
#include "puzzle_region.h"
#include "physics/falling_path.h"
#include "physics/puzzle_path.h"
#include "graphics/graphics.h"
#include "effect/erase_effect.h"
#include "render_manager.h"
#include "image_manager.h"
#include <iostream>
//////////////

using namespace std;

/**
* Constructor
**/
PuzzleRegion::PuzzleRegion()
{	
	queueRegion = NULL;
	semaphore = SDL_CreateSemaphore( 1 );
	adding = false;
	finishing = false;
	matchPattern = false;
	
	for( int i = 0; i < PUZZLE_PATTERN_SIZE; i++ )
		for( int j = 0; j < PUZZLE_PATTERN_SIZE; j++ )
			pattern[i][j] = ' ';
}

/**
* Destructor
**/
PuzzleRegion::~PuzzleRegion()
{
	if( semaphore != NULL )
	{
		SDL_DestroySemaphore( semaphore );
	}
	
	for( int i = 0; i < (int)selections.size(); i++ )
	{
		delete selections[i];
		selections[i] = NULL;
	}
}

/**
* Loads a pattern to match.
* 
* @param pattern The pattern to match
**/
void PuzzleRegion::LoadPattern( char pattern[PUZZLE_PATTERN_SIZE][PUZZLE_PATTERN_SIZE] )
{
	int minX = PUZZLE_PATTERN_SIZE; int maxX = -1; int minY = PUZZLE_PATTERN_SIZE; int maxY = -1;
	for( int i = 0; i < PUZZLE_PATTERN_SIZE; i++ )
		for( int j = 0; j < PUZZLE_PATTERN_SIZE; j++ )
		{
			if( pattern[i][j] != ' ' )
			{
				if( i < minX ) minX = i;
				if( i > maxX ) maxX = i;
				if( j < minY ) minY = j;
				if( j > maxY ) maxY = j;
			}
			this->pattern[i][j] = pattern[i][j];
		}
	
	if( maxX != -1 )
	{
		patternXOffset = minX;
		patternYOffset = minY;
		patternWidth = maxX - minX + 1;
		patternHeight = maxY - minY + 1;
	}
	
	matchPattern = true;
	
	CheckPatterns();
}

/**
* Unloads the current pattern, if any.
**/
void PuzzleRegion::UnloadPattern()
{
	for( int i = 0; i < (int)selections.size(); i++ )
	{
		delete selections[i];
		selections[i] = NULL;
	}
	selections.clear();
	
	matchPattern = false;
}

/**
* Notify the region of an event.
* 
* Overridden from Region.
* 
* @param event The event that happened
* @return If the region used the event
**/
bool PuzzleRegion::ProcessEvent( SDL_Event event )
{
	if( event.type == SDL_MOUSEMOTION ) // hover logic for selections
	{
		PuzzleSelection* oldHover = NULL;
		for( int i = 0; i < (int)selections.size(); i++ )
		{
			if( selections[i]->hovered )
				oldHover = selections[i];
			selections[i]->hovered = false;
		}
		
		PuzzleSelection* hover = NULL;
		for( int i = 0; i < (int)selections.size(); i++ )
		{
			if( event.button.x >= selections[i]->x && 
				event.button.x <= selections[i]->x + selections[i]->width && 
				event.button.y >= selections[i]->y && 
				event.button.y <= selections[i]->y + selections[i]->height )
			{
				if( hover == NULL )
				{
					selections[i]->hovered = true;
					hover = selections[i];
				}
				else if( selections[i]->x < hover->x )
				{
					hover->hovered = false;
					selections[i]->hovered = true;
					hover = selections[i];
				}
				else if( selections[i]->y < hover->y )
				{
					hover->hovered = false;
					selections[i]->hovered = true;
					hover = selections[i];
				}
			}
		}
	}
	else if( event.type == SDL_MOUSEBUTTONDOWN ) // selection logic for selections
	{
		for( int i = 0; i < (int)selections.size(); i++ )
		{
			if( selections[i]->hovered )
			{
				selections[i]->selected = !selections[i]->selected;
			}
		}
		
		if (matchPattern)
			CheckPatterns();
	}
	
	return Region::ProcessEvent( event );
}

/**
* Notifies of time passing.
* 
* Overridden from Region.
* 
* @param The amount of time, in milliseconds, that passed since the last call
**/
void PuzzleRegion::TimePassed( int ms )
{
	Region::TimePassed( ms );
	
	if( (int)fallingObjects.size() > 0 ) // handle falling differently
	{
		for( int i = 0; i < (int)fallingObjects.size(); i++ )
		{
			if( fallingObjects[i]->GetPath()->GetY() + fallingObjects[i]->GetPath()->GetHeight() >= 
											GetBoundary()->GetY() + GetBoundary()->GetHeight() )
			{
				Path* path = new Path();
				path->SetPosition( fallingObjects[i]->GetPath()->GetX(), fallingObjects[i]->GetPath()->GetY() );
				fallingObjects[i]->SetPath( path );
				fallingObjects.erase( fallingObjects.begin() + i );
			}
			else
			{
				for( int o = 0; o < (int)objects.size(); o++ )
				{
					bool contains = false;
					for( int a = 0; a < (int)fallingObjects.size(); a++ )
						if( objects[o] == fallingObjects[a] )
							contains = true;
					
					if( !contains && objects[o] != fallingObjects[i] && !IsObjectActiveOrSimilar(objects[o]) &&
						fallingObjects[i]->GetPath()->GetY() + fallingObjects[i]->GetPath()->GetHeight() >= objects[o]->GetPath()->GetY() &&
						fallingObjects[i]->GetPath()->GetX() == objects[o]->GetPath()->GetX() )
					{
						Path* path = new Path();
						path->SetPosition( fallingObjects[i]->GetPath()->GetX(), fallingObjects[i]->GetPath()->GetY() );
						fallingObjects[i]->SetPath( path );
						fallingObjects.erase( fallingObjects.begin() + i );
					}
				}
			}
		}
		
		// If we are done with this falling phase.
		if( (int)fallingObjects.size() == 0 )
		{
			// Do something
		}
	}
	else if( GetActiveObject() != NULL )
	{
		if( !finishing )
		{
			// Check for collision with stationary pieces (including boundary)
			bool collision = false;
			if( GetActiveObject()->GetPath()->GetY() + GetActiveObject()->GetPath()->GetHeight() >= 
				GetBoundary()->GetY() + GetBoundary()->GetHeight() )
			{
				collision = true;
			}
			for( int o = 0; o < (int)objects.size(); o++ )
			{
				bool contains = false;
				for( int a = 0; a < (int)GetActiveObject()->GetAssociations().size(); a++ )
					if( objects[o] == GetActiveObject()->GetAssociations()[a] )
						contains = true;
				
				if( objects[o] != GetActiveObject() && !contains )
				{
					Area fa = Area( GetActiveObject()->GetPath()->GetX(), GetActiveObject()->GetPath()->GetY(), GetActiveObject()->GetPath()->GetWidth(), GetActiveObject()->GetPath()->GetHeight() );
					Area sa = Area( objects[o]->GetPath()->GetX(), objects[o]->GetPath()->GetY(), objects[o]->GetPath()->GetWidth(), objects[o]->GetPath()->GetHeight() );
					if( fa.GetY() + fa.GetHeight() >= sa.GetY() && 
						fa.GetY() <= sa.GetY() + sa.GetHeight() && 
						fa.GetX() == sa.GetX())
					{
						collision = true;
					}
				}
			}
			
			for( int i = 0; i < (int)GetActiveObject()->GetAssociations().size(); i++ )
			{
				Object* object = GetActiveObject()->GetAssociations()[i];
				
				if( object->GetPath()->GetY() + object->GetPath()->GetHeight() >= 
					GetBoundary()->GetY() + GetBoundary()->GetHeight() )
				{
					collision = true;
				}
				for( int o = 0; o < (int)objects.size(); o++ )
				{
					bool contains = false;
					for( int a = 0; a < (int)object->GetAssociations().size(); a++ )
						if( objects[o] == object->GetAssociations()[a] )
							contains = true;
					
					if( objects[o] != object && !contains )
					{
						Area fa = Area( object->GetPath()->GetX(), object->GetPath()->GetY(), object->GetPath()->GetWidth(), object->GetPath()->GetHeight() );
						Area sa = Area( objects[o]->GetPath()->GetX(), objects[o]->GetPath()->GetY(), objects[o]->GetPath()->GetWidth(), objects[o]->GetPath()->GetHeight() );
						if( fa.GetY() + fa.GetHeight() + 1 >= sa.GetY() && 
							fa.GetY() <= sa.GetY() + sa.GetHeight() && 
							fa.GetX() == sa.GetX())
						{
							collision = true;
						}
					}
				}
			}
			
			if( collision )
			{
				// Convert active object and associates' paths to falling path.
				int oldX = GetActiveObject()->GetPath()->GetX();
				int oldY = GetActiveObject()->GetPath()->GetY();
				double oldYVel = GetActiveObject()->GetPath()->GetYVel();
				FallingPath* path = new FallingPath(oldYVel);
				path->SetPosition( oldX, oldY );
				GetActiveObject()->SetPath( path );
				
				for( int i = 0; i < (int)GetActiveObject()->GetAssociations().size(); i++ )
				{
					Object* object = GetActiveObject()->GetAssociations()[i];
					
					oldX = object->GetPath()->GetX();
					oldY = object->GetPath()->GetY();
					FallingPath* path = new FallingPath(oldYVel);
					path->SetPosition( oldX, oldY );
					object->SetPath( path );
				}
				
				finishing = true;
			}
		}
		
		if( finishing )
		{
			// Freeze objects that finished falling
			if( GetActiveObject()->GetPath()->GetY() + GetActiveObject()->GetPath()->GetHeight() >= 
					GetBoundary()->GetY() + GetBoundary()->GetHeight() )
			{
				Path* path = new Path();
				path->SetPosition( GetActiveObject()->GetPath()->GetX(), GetActiveObject()->GetPath()->GetY() );
				GetActiveObject()->SetPath( path );
			}
			
			for( int o = 0; o < (int)objects.size(); o++ )
			{
				if( objects[o] != GetActiveObject() && GetActiveObject()->GetPath()->IsMoving() )
				{
					Area fa = Area( GetActiveObject()->GetPath()->GetX(), GetActiveObject()->GetPath()->GetY(), GetActiveObject()->GetPath()->GetWidth(), GetActiveObject()->GetPath()->GetHeight() );
					Area sa = Area( objects[o]->GetPath()->GetX(), objects[o]->GetPath()->GetY(), objects[o]->GetPath()->GetWidth(), objects[o]->GetPath()->GetHeight() );
					if( fa.GetY() + fa.GetHeight() >= sa.GetY() && 
						fa.GetY() <= sa.GetY() + sa.GetHeight() && 
						fa.GetX() == sa.GetX())
					{
						Path* path = new Path();
						path->SetPosition( GetActiveObject()->GetPath()->GetX(), GetActiveObject()->GetPath()->GetY() );
						GetActiveObject()->SetPath( path );
					}
				}
			}
			
			for( int a = 0; a < (int)GetActiveObject()->GetAssociations().size(); a++ )
			{
				Object* object = GetActiveObject()->GetAssociations()[a];
				
				if( object->GetPath()->GetY() + object->GetPath()->GetHeight() >= 
									GetBoundary()->GetY() + GetBoundary()->GetHeight() )
				{
					Path* path = new Path();
					path->SetPosition( object->GetPath()->GetX(), object->GetPath()->GetY() );
					object->SetPath( path );
				}
				
				for( int o = 0; o < (int)objects.size(); o++ )
				{
					if( objects[o] != object && object->GetPath()->IsMoving() )
					{
						Area fa = Area( object->GetPath()->GetX(), object->GetPath()->GetY(), object->GetPath()->GetWidth(), object->GetPath()->GetHeight() );
						Area sa = Area( objects[o]->GetPath()->GetX(), objects[o]->GetPath()->GetY(), objects[o]->GetPath()->GetWidth(), objects[o]->GetPath()->GetHeight() );
						if( fa.GetY() + fa.GetHeight() >= sa.GetY() && 
							fa.GetY() <= sa.GetY() + sa.GetHeight() && 
							fa.GetX() == sa.GetX())
						{
							Path* path = new Path();
							path->SetPosition( object->GetPath()->GetX(), object->GetPath()->GetY() );
							object->SetPath( path );
						}
					}
				}
			}
			
			bool moving = false;
			for( int a = 0; a < (int)GetActiveObject()->GetAssociations().size(); a++ )
			{
				if( GetActiveObject()->GetAssociations()[a]->GetPath()->IsMoving() )
					moving = true;
			}
			
			// If everything is ready for new pieces
			if( !moving && !GetActiveObject()->GetPath()->IsMoving() )
			{
				finishing = false;
				PuzzlePathFinished();
			}
		}
	}
}

/**
* Renders the objects on the background
* 
* Overridden from Region.
**/
void PuzzleRegion::Render()
{
	for( int i = 0; i < (int)objects.size(); i++ )
	{
		if( IsObjectActiveOrSimilar(objects[i]) && objects[i]->IsHovered() )
		{
			objects[i]->SetHover( false );
		}
	}
	
	Region::Render();
	
	for( int i = 0; i < (int)objects.size(); i++ )
	{
		if( objects[i]->IsHovered() )
		{
			ImageCustomRender* render = new ImageCustomRender();
			render->surface = ImageManager::GetManager()->GetImage(IMAGE_GEM_HOVER);
			render->x = objects[i]->GetPath()->GetX();
			render->y = objects[i]->GetPath()->GetY();
			render->width = render->surface->GetWidth();
			render->height = render->surface->GetHeight();
			RenderManager::GetManager()->AddCustomRender(render);
		}
	}
	
	for( int i = 0; i < (int)selections.size(); i++ )
	{
		Color color = selections[i]->hovered ? COLOR_RED : COLOR_WHITE;
		
		// RECTANGLE //
		RectCustomRender* render = new RectCustomRender();
		render->color = COLOR_BLACK;
		render->fill = false;
		render->x = selections[i]->x + 1;
		render->y = selections[i]->y + 1;
		render->width = selections[i]->width;
		render->height = selections[i]->height;
		RenderManager::GetManager()->AddCustomRender(render);
		
		render = new RectCustomRender();
		render->color = color;
		render->fill = false;
		render->x = selections[i]->x;
		render->y = selections[i]->y;
		render->width = selections[i]->width;
		render->height = selections[i]->height;
		RenderManager::GetManager()->AddCustomRender(render);
		
		// SELECTION BOX //
		render = new RectCustomRender();
		render->color = COLOR_BLACK;
		render->fill = false;
		render->x = selections[i]->x + 11;
		render->y = selections[i]->y + 11;
		render->width = 20;
		render->height = 20;
		RenderManager::GetManager()->AddCustomRender(render);
		
		render = new RectCustomRender();
		render->color = COLOR_WHITE;
		render->fill = selections[i]->selected;
		render->x = selections[i]->x + 10;
		render->y = selections[i]->y + 10;
		render->width = 20;
		render->height = 20;
		RenderManager::GetManager()->AddCustomRender(render);
	}
}

/**
* Notifies region to start dropping pieces. Will be taken out later.
**/
void PuzzleRegion::Start()
{
	adding = true;
		
	AddNewGem();
	
	adding = false;
}

/**
* Invoked when the puzzle path has finished dropping.
* 
* Overridden from PuzzlePathListener.
**/
void PuzzleRegion::PuzzlePathFinished()
{
	if( !adding )
	{
		adding = true;
		
		active->RemoveAllAssociations();
		
		if (matchPattern)
			CheckPatterns();
		
		AddNewGem();
	}
}

/**
* Adds a new gem piece to the region.
**/
void PuzzleRegion::AddNewGem()
{
	SDL_SemWait( semaphore );
	
	Path::Direction direction = Path::DIRECTION_NONE;
	
	if( GetActiveObject() != NULL )
	{
		direction = GetActiveObject()->GetPath()->GetKeyDirection();
		int oldX = GetActiveObject()->GetPath()->GetX();
		int oldY = GetActiveObject()->GetPath()->GetY();
		Path* path = new Path();
		path->SetPosition( oldX, oldY );
		GetActiveObject()->SetPath( path );
	}
	
	if( queueRegion )
	{
		QueueRegion::PuzzlePair* pair = queueRegion->GetTopPair();
		queueRegion->Dequeue();
		
		Object* first = pair->first;
		PuzzlePath* path = new PuzzlePath( ImageManager::GetManager()->GetImage( IMAGE_GREEN_GEM )->GetWidth() );
		path->SetListener( this );
		path->SetKeyDirection( direction );
		first->SetPath( path );
		first->SetPosition( GetBoundary()->GetX() + (ImageManager::GetManager()->GetImage( IMAGE_GREEN_GEM )->GetWidth() * 4), GetBoundary()->GetY() );
		AddObject( first );
		RenderManager::GetManager()->AddObject(first);
		SetActiveObject( first );
		
		Object* second = pair->second;
		second->SetPosition( first->GetPath()->GetX() + first->GetSurface()->GetWidth(), GetBoundary()->GetY() );
		AddObject( second );
		RenderManager::GetManager()->AddObject(second);
		first->AddAssociation( second );
	}
	
	adding = false;
	
	SDL_SemPost( semaphore );
}

/**
* Removes the given object from the region.
* 
* Overridden from Region.
* 
* @param object The object to remove
* @param del If the object should be deleted
**/
void PuzzleRegion::RemoveObject(Object* object, bool del)
{
	// Makes pieces fall if they were resting on the destroyed piece.
	for( int i = 0; i < (int)objects.size(); i++ )
	{
		if( object != objects[i] )
		{
			if( !IsObjectActiveOrSimilar(objects[i]) && 
					objects[i]->GetPath()->GetY() < object->GetPath()->GetY() &&
					objects[i]->GetPath()->GetX() == object->GetPath()->GetX() )
			{
				int oldX = objects[i]->GetPath()->GetX();
				int oldY = objects[i]->GetPath()->GetY();
				FallingPath* path = new FallingPath();
				path->SetPosition( oldX, oldY );
				objects[i]->SetPath( path );
				
				fallingObjects.push_back( objects[i] );
			}
		}
	}
	
	// If we are done with this falling phase
	if( (int)fallingObjects.size() == 0 )
	{
		// Do something
	}
	
	Region::RemoveObject(object);
}

/**
* Checks if any object is not supported, changes to falling if not.
**/
void PuzzleRegion::CheckForFalling()
{
	bool fall = true;
	while(fall)
	{
		fall = false;
		for( int i = 0; i < (int)objects.size(); i++ )
		{
			if( !IsObjectActiveOrSimilar(objects[i]) && !objects[i]->GetPath()->IsMoving() )
			{
				bool empty = true;
				for( int o = 0; o < (int)objects.size(); o++ )
				{
					if( i != o && !IsObjectActiveOrSimilar(objects[o]) && !objects[o]->GetPath()->IsMoving() &&
						objects[i]->GetPath()->GetY() + objects[i]->GetPath()->GetHeight() + 1 == objects[o]->GetPath()->GetY() &&
						objects[i]->GetPath()->GetX() == objects[o]->GetPath()->GetX() )
					{
						empty = false;
						break;
					}
				}
				if( empty )
				{
					int oldX = objects[i]->GetPath()->GetX();
					int oldY = objects[i]->GetPath()->GetY();
					FallingPath* path = new FallingPath();
					path->SetPosition( oldX, oldY );
					objects[i]->SetPath( path );
					
					fallingObjects.push_back( objects[i] );
					
					fall = true;
					break;
				}
			}
		}
	}
}

/**
* Calls for optional custom rendering.
* 
* Overridden from Region.
* 
* @returns If the region requires to flipped entirely (as opposed to flipping just the objects)
**/
bool PuzzleRegion::CustomRender()
{
	return true;
}

/**
* Populates the selection list with pattern matches.
**/
void PuzzleRegion::CheckPatterns()
{
	vector<PuzzleSelection*> selected;
	
	for( int i = 0; i < (int)selections.size(); i++ )
	{
		if( selections[i]->selected )
			selected.push_back( selections[i] );
		else
		{
			delete selections[i];
			selections[i] = NULL;
		}
	}
	
	selections.clear();
	
	for( int i = 0; i < (int)selected.size(); i++ )
	{
		selections.push_back( selected[i] );
	}
	
	int objectIds[PUZZLE_BOARD_WIDTH][PUZZLE_BOARD_HEIGHT];
	for( int x = 0; x < PUZZLE_BOARD_WIDTH; x++ )
		for( int y = 0; y < PUZZLE_BOARD_HEIGHT; y++ )
			objectIds[x][y] = -1;
			
	for( int i = 0; i < (int)objects.size(); i++ )
	{
		if( !objects[i]->GetPath()->IsMoving() )
		{
			int x = objects[i]->GetPath()->GetX() - GetBoundary()->GetX();
			x = (x / (objects[i]->GetPath()->GetWidth()));
			int y = objects[i]->GetPath()->GetY() - GetBoundary()->GetY();
			y = (y / (objects[i]->GetPath()->GetHeight()));
			objectIds[x][y] = objects[i]->GetID();
		}
	}
	
	for( int x = -PUZZLE_PATTERN_SIZE; x < PUZZLE_BOARD_WIDTH; x++ )
		for( int y = -PUZZLE_PATTERN_SIZE; y < PUZZLE_BOARD_HEIGHT; y++ )
		{
			bool failed = false;
			for( int px = 0; px < PUZZLE_PATTERN_SIZE; px++ )
			{
				for( int py = 0; py < PUZZLE_PATTERN_SIZE; py++ )
				{
					// if there is something in the pattern to match
					if( pattern[px][py] != ' ' )
					{
						// if the bounds are OK
						if( x + px < 0 || y + py < 0 || x + px >= PUZZLE_BOARD_WIDTH || y + py >= PUZZLE_BOARD_HEIGHT )
						{
							failed = true;
							break;
						}
						else if( pattern[px][py] != objectIds[x + px][y + py] ) // exact match for now
						{
							failed = true;
							break;
						}
					}
				}
				
				if( failed )
					break;
			}
			
			if( !failed && (int)objects.size() > 0 )
			{
				int width = objects[0]->GetPath()->GetWidth();
				int selectX = GetBoundary()->GetX() + ( ( x + patternXOffset ) * objects[0]->GetPath()->GetWidth() );
				int selectY = GetBoundary()->GetY() + GetBoundary()->GetHeight() - ( ( PUZZLE_BOARD_HEIGHT - ( y + patternYOffset ) ) * objects[0]->GetPath()->GetWidth() );
				int selectWidth = width * patternWidth;
				int selectHeight = width * patternHeight;
				
				bool valid = true;
				for( int s = 0; s < (int)selections.size(); s++ )
				{
					if( selections[s]->selected && 
						selectX < selections[s]->x + selections[s]->width &&
						selectX + selectWidth > selections[s]->x &&
						selectY < selections[s]->y + selections[s]->height &&
						selectY + selectHeight > selections[s]->y )
					{
						valid = false;
					}
				}
				
				if( valid )
				{
					PuzzleSelection* selection = new PuzzleSelection();
					selection->hovered = false;
					selection->selected = false;
					selection->x = selectX; //GetBoundary()->GetX() + ( ( x + patternXOffset ) * ( objects[0]->GetPath()->GetWidth() + 1 ) );
					selection->y = selectY; //GetBoundary()->GetY() + GetBoundary()->GetHeight() - ( ( PUZZLE_BOARD_HEIGHT - ( y + patternYOffset ) ) * ( objects[0]->GetPath()->GetWidth() + 1 ) );
					selection->width = selectWidth; //( objects[0]->GetPath()->GetWidth() + 1 ) * patternWidth;
					selection->height = selectHeight; //( objects[0]->GetPath()->GetWidth() + 1 ) * patternHeight;
					selections.push_back(selection);
				}
				else
				{
					// invalid
				}
			}
		}
}

/**
* Clears all checked selections from the board.
**/
void PuzzleRegion::ClearSelections()
{
	if( (int)objects.size() > 0 )
	{
		Object* object;
		for( int i = 0; i < (int)selections.size(); i++ )
		{
			if( selections[i]->selected )
			{
				int startX = selections[i]->x + (objects[0]->GetPath()->GetWidth() / 2);
				int startY = selections[i]->y + (objects[0]->GetPath()->GetWidth() / 2);
				
				for( int x = 0; x < patternWidth; x++ )
					for( int y = 0; y < patternHeight; y++ )
					{
						object = GetObjectByCoordinate(startX + ((objects[0]->GetPath()->GetWidth() + 1) * x), 
								startY + ((objects[0]->GetPath()->GetWidth() + 1) * y));
						if( object != NULL )
						{
							RemoveObject( object );
						}
					}
				
				delete selections[i];
				selections[i] = NULL;
			}
		}
	}
	
	selections.clear();
	
	matchPattern = false;
}

void PuzzleRegion::CancelSelection()
{
	UnloadPattern();
}

void PuzzleRegion::SetSelection(vector<vector<char> > pattern)
{
	char testPattern[PUZZLE_PATTERN_SIZE][PUZZLE_PATTERN_SIZE];
	for( int i = 0; i < (int)pattern.size(); i++ )
		for( int j = 0; j < (int)pattern.size(); j++ )
			testPattern[i][j] = pattern[i][j];
	
	LoadPattern( testPattern );
}
